package com.weipai.springboot.base.interceptor;


import com.weipai.springboot.shiro.AuthRealm;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.mgt.RememberMeManager;
import org.apache.shiro.session.SessionListener;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO;
import org.apache.shiro.session.mgt.eis.MemorySessionDAO;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;

import javax.servlet.Filter;
import java.util.*;

/**
 * @author: wangsaichao
 * @date: 2018/5/10
 * @description: Shiro配置
 */
@Configuration
public class ShiroConfig {


	/**
	 * ShiroFilterFactoryBean 处理拦截资源文件问题。
	 * 注意：初始化ShiroFilterFactoryBean的时候需要注入：SecurityManager
	 * Web应用中,Shiro可控制的Web请求必须经过Shiro主过滤器的拦截
	 * @param securityManager
	 * @return
	 */
	@Bean(name = "shirFilter")
	public ShiroFilterFactoryBean shiroFilter(@Qualifier("securityManager") SecurityManager securityManager) {

		ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();

		//必须设置 SecurityManager,Shiro的核心安全接口
		shiroFilterFactoryBean.setSecurityManager(securityManager);
		Map<String,Filter> filterMap = new HashMap<>();
		filterMap.put("authc", new MyAuthenticationFilter());//认证
		shiroFilterFactoryBean.setFilters(filterMap);
		//这里的/login是后台的接口名,非页面，如果不设置默认会自动寻找Web工程根目录下的"/login.jsp"页面
	/*	shiroFilterFactoryBean.setLoginUrl("/login");
		//这里的/index是后台的接口名,非页面,登录成功后要跳转的链接
		shiroFilterFactoryBean.setSuccessUrl("/index");
		//未授权界面,该配置无效，并不会进行页面跳转
		shiroFilterFactoryBean.setUnauthorizedUrl("/unauthorized");*/

		//自定义拦截器限制并发人数,参考博客：
		//LinkedHashMap<String, Filter> filtersMap = new LinkedHashMap<>();
		//限制同一帐号同时在线的个数
		//filtersMap.put("kickout", kickoutSessionControlFilter());
		//shiroFilterFactoryBean.setFilters(filtersMap);

		// 配置访问权限 必须是LinkedHashMap，因为它必须保证有序
		// 过滤链定义，从上向下顺序执行，一般将 /**放在最为下边 一定要注意顺序,否则就不好使了
		LinkedHashMap<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
		//配置不登录可以访问的资源，anon 表示资源都可以匿名访问
		filterChainDefinitionMap.put("/user/login", "anon");
		filterChainDefinitionMap.put("/user/loginOut", "anon");
		filterChainDefinitionMap.put("/role/**", "anon");
		filterChainDefinitionMap.put("/sms/sendCode", "anon");

		//-------------
		filterChainDefinitionMap.put("/help/helpCateList", "anon");
		filterChainDefinitionMap.put("/demand/demandListByCity/**/**/**", "anon");
		filterChainDefinitionMap.put("/personal/getDemandCategory", "anon");
		filterChainDefinitionMap.put("artisan/recommendArtisan", "anon");
		filterChainDefinitionMap.put("/role/getMenusByRoleId/**", "anon");
		filterChainDefinitionMap.put("/dataStatistics/homePage", "anon");
		filterChainDefinitionMap.put("/user/thirdPartyLogin", "anon");
		filterChainDefinitionMap.put("/user/error", "anon");
		filterChainDefinitionMap.put("/customer/register", "anon");
		filterChainDefinitionMap.put("/user/saveAdminLoginRecord", "anon");
		filterChainDefinitionMap.put("/user/verifyCustomer", "anon");
		filterChainDefinitionMap.put("/goods/getProductInfoByProductId", "anon");
		filterChainDefinitionMap.put("/pcNews/list", "anon");
		filterChainDefinitionMap.put("/advertising/list", "anon");
		filterChainDefinitionMap.put("/goods/searchGoodsByKeyWord", "anon");
		filterChainDefinitionMap.put("/goods/searchBySoldOutGoods", "anon");
		filterChainDefinitionMap.put("/goods/searchSpecialGoods", "anon");
		filterChainDefinitionMap.put("/productCategory/getTopCategory", "anon");
		filterChainDefinitionMap.put("/picture/getImgByPictureCategoryId/**", "anon");
		filterChainDefinitionMap.put("/productCategory/getAllProductCategory", "anon");
		filterChainDefinitionMap.put("/help/helpCateList", "anon");
		filterChainDefinitionMap.put("/help/helpList", "anon");
		filterChainDefinitionMap.put("/specialOffer/getSpecialOffer", "anon");
		filterChainDefinitionMap.put("/brand/getHotBrand", "anon");
		filterChainDefinitionMap.put("/brand/list/**/**/**/**/**/**", "anon");
		filterChainDefinitionMap.put("/integralGoods/list/", "anon");
		filterChainDefinitionMap.put("/goods/searchHotCategory", "anon");
		filterChainDefinitionMap.put("/storage/locateStorage", "anon");
		filterChainDefinitionMap.put("/productCategory/getThirdCategoryByTopId", "anon");

		filterChainDefinitionMap.put("/productCategory/getThirdCategoryByTopId/**", "anon");
		filterChainDefinitionMap.put("/shopCart/addToShopCart", "anon");
		filterChainDefinitionMap.put("/customer/resetPasswords", "anon");
		filterChainDefinitionMap.put("/common/saveFile", "anon");
		filterChainDefinitionMap.put("/common/searchCbaer", "anon");
		filterChainDefinitionMap.put("/temp-rainy/*", "anon");

		filterChainDefinitionMap.put("/goods/searchRecommendGoods", "anon");
		filterChainDefinitionMap.put("/integralGoods/list/**", "anon");
		filterChainDefinitionMap.put("/artisan/recommendArtisan", "anon");
		filterChainDefinitionMap.put("/integralGoods/getIntegralGoodsById/**", "anon");
//		filterChainDefinitionMap.put(, "anon");
//		filterChainDefinitionMap.put(, "anon");

		//----------
	/*	filterChainDefinitionMap.put("/dataStatistics/**", "anon");*/
/*		filterChainDefinitionMap.put("/css/**", "anon");
		filterChainDefinitionMap.put("/js/**", "anon");
		filterChainDefinitionMap.put("/img/**", "anon");
		filterChainDefinitionMap.put("/druid/**", "anon");
		//logout是shiro提供的过滤器
		filterChainDefinitionMap.put("/logout", "logout");*/
		//此时访问/userInfo/del需要del权限,在自定义Realm中为用户授权。
		//filterChainDefinitionMap.put("/userInfo/del", "perms[\"userInfo:del\"]");

		//其他资源都需要认证  authc 表示需要认证才能进行访问
		filterChainDefinitionMap.put("/**", "authc");

		shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);

		return shiroFilterFactoryBean;
	}

	/**
	 * 配置核心安全事务管理器
	 * @param shiroRealm
	 * @return
	 */
	@Bean(name="securityManager")
	public SecurityManager securityManager(@Qualifier("authRealm") AuthRealm shiroRealm) {
		DefaultWebSecurityManager securityManager =  new DefaultWebSecurityManager();
		//设置自定义realm.
		securityManager.setRealm(shiroRealm);
		/*securityManager.setSessionManager(sessionManager());*/
		//配置记住我 参考博客：
		//securityManager.setRememberMeManager(rememberMeManager());

		//配置 redis缓存管理器 参考博客：
		//securityManager.setCacheManager(getEhCacheManager());

		//配置自定义session管理，使用redis 参考博客：
		//securityManager.setSessionManager(sessionManager());

		return securityManager;
	}
	@Bean
	public SessionManager sessionManager(){
		DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
		Collection<SessionListener> listeners = new ArrayList<SessionListener>();
		listeners.add(new ShiroSessionListener());
		sessionManager.setSessionListeners(listeners);
		sessionManager.setSessionDAO(sessionDAO());
		return sessionManager;
	}

	/**
	 * 配置Shiro生命周期处理器
	 * @return
	 */
	@Bean(name = "lifecycleBeanPostProcessor")
	public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
		return new LifecycleBeanPostProcessor();
	}
	@Bean
	public SessionDAO sessionDAO() {
		MemorySessionDAO sessionDAO = new MemorySessionDAO();
		return sessionDAO;
	}
	/**
	 *  身份认证realm; (这个需要自己写，账号密码校验；权限等)
	 * @return
	 */
	@Bean
	public AuthRealm shiroRealm(){
		AuthRealm shiroRealm = new AuthRealm();
		return shiroRealm;
	}

	/**
	 * 必须（thymeleaf页面使用shiro标签控制按钮是否显示）
	 * 未引入thymeleaf包，Caused by: java.lang.ClassNotFoundException: org.thymeleaf.dialect.AbstractProcessorDialect
	 * @return
	 *//*
	@Bean
	public ShiroDialect shiroDialect() {
		return new ShiroDialect();
	}*/


}